特殊数字
- 如果两个数a和b,a的所有真因数之和等于b,b的所有真因数之和等于a,则称a,b是一对亲和数。求50000以内的所有亲和数,真因数不包括本身。
- 只有1和本身作为因子的数称作素数。求1000以内的所有素数,习惯上1不作为素数。
- 我们把只包含因子2、3和5的数称为丑数。求按从小到大的顺序排列的第1500个丑数。习惯上我们把1当做第一个丑数。
1、思路:
常规方法:对每个数i(从1到N)进行处理,处理的方法是用j(从1到i/2)进行取余,看是否为0。能整除的话,sum[i] += j。
伴随数组:从因子2开始处理,对于下标是2的倍数说明因子含有2;接下去处理因子3,对于下标是3的倍数说明因子含有3;依次类推。
1 #include <iostream> 2 3 using namespace std; 4 5 const int N = 50000; 6 7 int main() 8 { 9 int i, j, sum[N + 1]; 10 for (i = 1; i <= N; i++) 11 sum[i] = 1; //1是所有数的真因数所以全部置1 12 for (i = 2; i <= N >> 1; i++) 13 { 14 j = i << 1; //从2倍开始加,因为是真因数,不包含本身 15 while (j <= N) 16 { 17 sum[j] += i; 18 j += i; //往3倍、4倍...n倍上加 19 } 20 } 21 for (i = 200; i <= N; i++) 22 { 23 if (sum[i] > i && sum[i] <= N && sum[sum[i]] == i) 24 cout << i << " " << sum[i] << endl; 25 } 26 return 0; 27 }
2、思路:
常规方法:对每个数i(从2到N)进行判断是否是素数,判断的规则是用j(从2到sqrt(i))进行取余,看是否为0。能整除的话说明不是素数。
伴随数组:筛选法,维护prime的bool数组,当下标为2、3、4...的倍数时,标记为false。
1 #include <stdio.h> 2 #include <math.h> 3 4 #define N 100 5 6 int main() 7 { 8 int i, j; 9 bool prime[N + 1]; 10 for (i = 1; i <= N; i++) 11 prime[i] = true; 12 prime[1] = false; 13 for (i = 2; i <= sqrt((double)N); i++) 14 { 15 if (prime[i]) 16 { 17 j = i << 1; 18 while (j <= N) 19 { 20 prime[j] = false; 21 j += i; 22 } 23 } 24 } 25 for (int i = 1; i <= N; i++) 26 if (prime[i]) printf("%d ", i); 27 return 0; 28 }